<?php
/**
 * Note: 自定义函数库
 * Date: 2019/12/2
 * Time: 16:52
 */

if (!function_exists('responseData')) {

    /**
     * 返回数据
     * @param array $data
     * @param string $message
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    function responseData($data = [], $message = '') {
        return response([
            'code' => 0,
            'message' => $message,
            'data' => $data
        ]);
    }
}

if (!function_exists('responseMessage')) {

    /**
     * 返回数据
     * @param string $message
     * @param array $data
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    function responseMessage($message = '', $data = []) {
        return response([
            'code' => 0,
            'message' => $message ?: __('api.success'),
            'data' => $data
        ]);
    }
}

if (!function_exists('responseException')) {

    /**
     * 返回数据
     * @param $message
     * @param array $data
     * @param int $code
     * @param int $httpCode
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    function responseException($message = '', $data = [], $code = 422, $httpCode = 422) {
        return response([
            'code' => $code,
            'message' => $message ?: __('api.failed'),
            'data' => $data
        ], $httpCode);
    }
}

if (!function_exists('id_encode')) {
    /**
     * id加密
     * @param $id
     * @return mixed
     */
    function id_encode($id) {
        return app(\Delight\Ids\Id::class)->obfuscate($id);
    }
}

if (!function_exists('id_decode')) {
    /**
     * id解密
     * @param $id
     * @return mixed
     */
    function id_decode($id) {
        return app(\Delight\Ids\Id::class)->deobfuscate($id);
    }
}

if (!function_exists('string_hide')) {
    /**
     * 隐藏字符串
     * @param $string
     * @param int $start
     * @param int $length
     * @return mixed
     */
    function string_hide($string, $start = 0, $length = 0)
    {
        if (empty($start)) {
            $start = floor(strlen($string) / 3);
        }
        if (empty($length)) {
            $length = ceil(strlen($string) / 3);
        }

        return substr_replace($string, str_repeat('*', $length), $start, $length);
    }
}

if (!function_exists('isJson')) {
    /**
     * 判断是否为 JSON 格式
     * todo 升级 laravel7 后如果有相同方法, 删除此方法
     * @param $string
     * @return bool
     */
    function isJson($string) {
        json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }
}

if (!function_exists('getRouteTranslate')) {

    /**
     * 路由对应翻译名称, 路由名称按照约定为 module.action 的形式, 方便使用翻译文件
     * @param $route
     * @return string|string[]
     */
    function getRouteTranslate($route)
    {
        if (strpos($route, '.') !== false) {
            list($module, $action,) = explode('.', $route);
        } else {
            $module = $route;
            $action = '';
        }

        $translateModule = $translateAction =  '';

        if (__("routes.module.{$module}") === "routes.module.{$module}") {
            $translateModule .= $module;
        } else {
            $translateModule .= __("routes.module.{$module}");
        }

        if (__("routes.action.{$action}") === "routes.action.{$action}") {
            $translateAction .= $action;
        } else {
            $translateAction .= __("routes.action.{$action}");
        }

        return $translateModule && $translateAction ? $translateModule.'.'.$translateAction : $translateModule;
    }
}

if (!function_exists('verifyOperationPassword')) {
    /**
     * 校验操作密码
     * @param $password
     * @return bool
     */
    function verifyOperationPassword($password)
    {
        return config('game.operation_password') == $password;
    }
}

if (!function_exists('converTimeToDHMS')) {
    /**
     * 秒数转换成中文
     * @param $seconds
     * @return string
     */
    function converTimeToDHMS($seconds)
    {
        $seconds = (int)$seconds;
        if ($seconds <= 0) {
            return '0秒';
        }
        $day = floor($seconds / 0x15180);
        $hour = floor(($seconds % 0x15180) / 0xe10);
        $minute = floor(($seconds % 0xe10) / 60);
        $second = $seconds % 60;
        $str = '';
        if ($day > 0) {
            $str .= sprintf("%d天", $day);
        }
        if ($hour > 0) {
            $str .= sprintf("%d小时", $hour);
        }
        // 没超过一天 显示分钟
        if ($day == 0 && $minute > 0) {
            $str .= sprintf("%d分钟", $minute);
        }
        // 没超过一小时 显示秒
        if ($day == 0 && $hour == 0 && $second > 0) {
            $str .= sprintf("%d秒", $second);
        }
        if ($str == '') {
            $str = '0秒';
        }
        return $str;
    }
}

if (!function_exists('getClientIp')) {
    /**
     * 获取客户端IP
     * @return array|false|mixed|string
     */
    function getClientIp() {
        if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
            $ip = getenv("HTTP_CLIENT_IP");
        } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
            $ip = getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
            $ip = getenv("REMOTE_ADDR");
        } else if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
            $ip = $_SERVER['REMOTE_ADDR'];
        } else {
            $ip = "unknown";
        }
        return ($ip);
    }
}

if (!function_exists('getCdnUrl')) {
    /**
     * 获取cdn url
     * @param string $path
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCdnUrl($path = '') {
        if (substr($path, 0, 4) === 'http') return $path;
        if (config('filesystems.disks.oss.cdn')) {
            return config('filesystems.disks.oss.cdn').'/'.config('filesystems.disks.oss.root', '').$path;
        }
        return config('app.url').(substr($path, 0, 1) === '/' ? '' : '/').$path;
    }
}

if (!function_exists('getCdnSiteUrl')) {
    /**
     * 获取cdn url
     * @param string $path
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCdnSiteUrl(string $path = '') {
        if (substr($path, 0, 4) === 'http') return $path;
        if ($url = config('game.cdn_site_url')) return $url.$path;
        return config('app.url').$path;
    }
}

if (!function_exists('human_filesize')) {

    /**
     * 返回可读性更好的文件尺寸
     * @param $bytes
     * @param int $decimals
     * @return string
     */
    function humanFilesize($bytes, $decimals = 2) {
        $size = ['B', 'kB', 'MB', 'GB', 'TB', 'PB'];
        $factor = floor((strlen($bytes) - 1) / 3);

        return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor];
    }
}

if (!function_exists('sencrypt')) {
    /**
     * 加密 简易版
     * @param $str
     * @return string
     */
    function sencrypt($str) {
        $base64Str = base64_encode(strrev($str.'simon'));
        $first = substr($base64Str, 3, 3);
        $sencond = substr($base64Str, 0, 3);
        return $first.$sencond.substr($base64Str, 6);
    }
}

if (!function_exists('sdecrypt')) {
    /**
     * 解密 简易版
     * @param $base64Str
     * @return false|string
     */
    function sdecrypt($base64Str) {
        $first = substr($base64Str, 3, 3);
        $sencond = substr($base64Str, 0, 3);
        $str = base64_decode($first.$sencond.substr($base64Str, 6));
        return substr(strrev($str), 0, -5);
    }
}

if (!function_exists('transUnit2Number')) {
    /**
     * 将数值中的单位转换为整数形式
     * @param $value
     * @return float|int
     */
    function transUnit2Number($value) {
        $number = 1;
        if (strtolower(substr($value, -1)) === 'e') {
            $number = 100000000;
        } else if (strtolower(substr($value, -1)) === 'w') {
            $number = 10000;
        }
        // 只保留数字和小数点
        return preg_replace('/[^\d\.]+/', '', $value) * $number;
    }
}

if (!function_exists('transNumber2Unit')) {
    /**
     * 将整数形式转换为数值中的单位
     * @param $value
     * @return string
     */
    function transNumber2Unit($value) {
        if ($value > 100000000) {
            $text = sprintf("%d亿", $value/100000000);
        } else if ($value > 10000) {
            $text = sprintf("%d万", $value/10000);
        } else {
            $text = $value;
        }
        return $text;
    }
}

if (!function_exists('getRand')) {
    /**
     * 随机返回一个key
     * @param $arr
     * @return false|int|string
     */
    function getRand($arr) {
        $num = array_sum($arr);
        $result = false;
        foreach ($arr as $k => $v) {
            $rand = mt_rand(1, $num);
            if ($rand <= $v) {
                $result = $k;
                break;
            } else {
                $num -= $v;
            }
        }
        return $result;
    }
}

if (!function_exists('numberFixed')) {
    /**
     * 数字校正位数
     * @param $val
     * @param int $toFixed
     * @return float|int
     */
    function numberFixed($val, int $toFixed = 2) {
        if (!is_numeric($val)) return $val;
        if (!$val) return 0;
        return floatval(sprintf("%.{$toFixed}f", $val));
    }
}

if (!function_exists('humanNumber')) {
    /**
     * 加入千分位
     * @param $val
     * @param int $toFixed
     * @return int|mixed|string
     */
    function humanNumber($val, int $toFixed = 0) {
        if (!is_numeric($val)) return $val;
        if (!$val) return 0;
        return number_format(sprintf("%.{$toFixed}f", $val));
    }
}

if (!function_exists('adminNodeId')) {
    /**
     * 后台节点ID
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function adminNodeId() {
        return config('admin.node_id', 0);
    }
}

if (!function_exists('dateWeekReal')) {
    /**
     * 和mysql %Y-$u 一致的周数
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function dateWeekReal($tm) {
        $tm = strtotime($tm);
        $w = date('w', $tm) == 0 ? 7 : date('w', $tm);
        if (date('W', $tm) >= 52) {
            $date = $tm - ($w - 1) * 24 * 3600;
        } else {
            $date = $tm + (7 - $w) * 24 * 3600;
        }
        return date("Y-W", $date);
    }
}

if (!function_exists('getCurrencyBulletScale')) {
    /**
     * 获取奶酪币值 1元=多少奶酪
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCurrencyBulletScale($fen = false): int {
        $scale = config('game.currency_bullet_scale');
        if ($fen) $scale /= 100;
        return $scale;
    }
}

if (!function_exists('getCurrencyHbScale')) {
    /**
     * 获取棒棒糖币值 1元多少棒棒糖
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCurrencyHbScale($fen = false): int {
        $scale = config('game.currency_hb_scale');
        if ($fen) $scale /= 100;
        return $scale;
    }
}

if (!function_exists('getCurrencyTicketScale')) {
    /**
     * 获取点券币值 1元多少点券
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCurrencyTicketScale($fen = false): float {
        $scale = config('game.currency_ticket_scale');
        if ($fen) $scale /= 100;
        return $scale;
    }
}

if (!function_exists('getCurrency2Rmb')) {
    /**
     * 获取货币对应价值
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
     */
    function getCurrency2Rmb(int $bullet, int $hb = 0): int {
        $rmb = 0;
        if ($bullet) $rmb += ($bullet / getCurrencyBulletScale());
        if ($hb) $rmb += ($hb / getCurrencyHbScale());
        return $rmb * 100;
    }
}

if (!function_exists('hasEnableCustomer')) {
    /**
     * 启用客服后台
     * @return bool
     */
    function hasEnableCustomer(): bool {
       return config('admin.enable_customer', false);
    }
}

if (!function_exists('hasEnableApi')) {
    /**
     * 启用API
     * @return bool
     */
    function hasEnableApi(): bool {
        return config('admin.enable_api', true);
    }
}

if (!function_exists('hasEnableCron')) {
    /**
     * 启用定时任务
     * @return bool
     */
    function hasEnableCron(): bool {
        // 客服后台 直接退出
        if (hasEnableCustomer()) return false;

        return config('admin.enable_cron', true);
    }
}

if (!function_exists('ip2long6')) {
    /**
     * IPV6 地址转换为整数
     * @param $ipv6
     * @return string
     */
    function ip2long6($ipv6) {
        $ip_n = inet_pton($ipv6);
        $bits = 15; // 16 x 8 bit = 128bit
        $ipv6long = '';
        while ($bits >= 0) {
            $bin = sprintf("%08b", (ord($ip_n[$bits])));
            $ipv6long = $bin . $ipv6long;
            $bits--;
        }
        return gmp_strval(gmp_init($ipv6long, 2), 10);
    }
}

if (!function_exists('long2ip6')) {
    /**
     * 整数转换为 IPV6 地址
     * @param $ipv6long
     * @return string
     */
    function long2ip6($ipv6long) {

        $bin = gmp_strval(gmp_init($ipv6long, 10), 2);
        if (strlen($bin) < 128) {
            $pad = 128 - strlen($bin);
            for ($i = 1; $i <= $pad; $i++) {
                $bin = "0" . $bin;
            }
        }
        $bits = 0;
        $ipv6 = '';
        while ($bits <= 7) {
            $bin_part = substr($bin, ($bits * 16), 16);
            $ipv6 .= dechex(bindec($bin_part)) . ":";
            $bits++;
        }
        // compress
        return inet_ntop(inet_pton(substr($ipv6, 0, -1)));
    }
}

if (!function_exists('isIpv6')) {

    /**
     * 是否是IPV6
     * @param string $ip
     * @return bool
     */
    function isIpv6(string $ip) {

        return strpos($ip, ':') !== false;
    }
}

if (!function_exists('ipv6_numeric')) {
    /**
     * @param $ip
     * @return string
     */
    function ipv6_numeric($ip) {
        $binNum = '';
        foreach (unpack('C*', inet_pton($ip)) as $byte) {
            $binNum .= str_pad(decbin($byte), 8, "0", STR_PAD_LEFT);
        }
        // $binNum is now a human readable string, but in binary.
        // If you have the gmp PHP extension, you can convert it to decimal
        return gmp_strval(gmp_init(ltrim($binNum, '0'), 2), 10);
    }
}

if (!function_exists('isStage')) {
    /**
     * 是否测试环境
     * @return bool
     */
    function isStage(): bool {
        return app()->environment('stage');
    }
}

if (!function_exists('isAnchor')) {
    /**
     * 是否主播环境
     * @return bool
     */
    function isAnchor(): bool {
        return app()->environment('anchor');
    }
}

if (!function_exists('isCustomer')) {
    /**
     * 是否客服环境
     * @return bool
     */
    function isCustomer(): bool {
        return app()->environment('customer');
    }
}

if (!function_exists('filterEmoji')) {
    /**
     * 过滤文本中的emoji表情
     * @param $str
     * @return array|string|string[]|null
     */
    function filterEmoji($str) {
        return preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);
    }
}

if (!function_exists('bcAddBatch')) {
    /**
     * 多个数相加
     * @param array $numbers
     * @param int $scale
     * @return string
     */
    function bcAddBatch(array $numbers, int $scale = 2): string {
        $result = '0';
        foreach ($numbers as $number) {
            $result = bcadd($result, $number, $scale);
        }
        return $result;
    }
}

if (!function_exists('bcSubBatch')) {
    /**
     * 多个数相减
     * @param array $numbers
     * @param int $scale
     * @return string
     */
    function bcSubBatch(array $numbers, int $scale = 2): string
    {
        $result = array_shift($numbers);
        foreach ($numbers as $number) {
            $result = bcsub($result, $number, $scale);
        }
        return $result;
    }
}

if (!function_exists('calcDivision')) {
    /**
     * 除法
     * @param int|float $a
     * @param int|float $b
     * @return int|float
     */
    function calcDivision(int|float $a, int|float $b): int|float
    {
        return $b ? $a/$b : 0;
    }
}
